package com.farm.kaiping.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.farm.common.security.SecurityUtils;
import com.farm.kaiping.entity.SysMenu;
import com.farm.kaiping.po.SysMenuPO;
import com.farm.kaiping.mapper.SysMenuMapper;
import com.farm.kaiping.service.SysMenuService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.farm.common.util.StringRange;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜单权限表(SysMenu)表服务实现类
 *
 * @author zhuhui
 * @since 2024-11-26 22:58:21
 */
@Service
@Slf4j
@AllArgsConstructor
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
    
	private LambdaQueryWrapper<SysMenu> generateQueryWrapper(SysMenuPO sysMenuPO){
		LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
		// 菜单ID
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getMenuId()), SysMenu::getMenuId, sysMenuPO.getMenuId());
		queryWrapper.in(ObjectUtil.isNotEmpty(sysMenuPO.getMenuIdList()), SysMenu::getMenuId, sysMenuPO.getMenuIdList());
		// 菜单名称
		queryWrapper.like(ObjectUtil.isNotEmpty(sysMenuPO.getName()), SysMenu::getName, sysMenuPO.getName());
		// 权限
		queryWrapper.like(ObjectUtil.isNotEmpty(sysMenuPO.getPermission()), SysMenu::getPermission, sysMenuPO.getPermission());
		// 权限路径
		queryWrapper.like(ObjectUtil.isNotEmpty(sysMenuPO.getPath()), SysMenu::getPath, sysMenuPO.getPath());
		// 父菜单ID
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getParentId()), SysMenu::getParentId, sysMenuPO.getParentId());
		queryWrapper.in(ObjectUtil.isNotEmpty(sysMenuPO.getParentIdList()), SysMenu::getParentId, sysMenuPO.getParentIdList());
		// 图标
		queryWrapper.like(ObjectUtil.isNotEmpty(sysMenuPO.getIcon()), SysMenu::getIcon, sysMenuPO.getIcon());
		// 排序值
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getSort()), SysMenu::getSort, sysMenuPO.getSort());
		// 保持有效
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getKeepAlive()), SysMenu::getKeepAlive, sysMenuPO.getKeepAlive());
		// 菜单类型,0:菜单 1:按钮
		queryWrapper.like(ObjectUtil.isNotEmpty(sysMenuPO.getType()), SysMenu::getType, sysMenuPO.getType());
		// 菜单类型；0--web；1--app
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getDeviceType()), SysMenu::getDeviceType, sysMenuPO.getDeviceType());
		// 是否可以创建子项目；0--可以；1--不可以
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getCreateChildren()), SysMenu::getCreateChildren, sysMenuPO.getCreateChildren());
		// 是否删除(0否1是)
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getDelFlag()), SysMenu::getDelFlag, sysMenuPO.getDelFlag());
        queryWrapper.eq(ObjectUtil.isEmpty(sysMenuPO.getDelFlag()), SysMenu::getDelFlag, 0);
		// 新增时间
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getCreateTime()), SysMenu::getCreateTime, sysMenuPO.getCreateTime());
		// 创建人ID
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getCreateUserId()), SysMenu::getCreateUserId, sysMenuPO.getCreateUserId());
		// 创建人姓名
		queryWrapper.like(ObjectUtil.isNotEmpty(sysMenuPO.getCreateUserName()), SysMenu::getCreateUserName, sysMenuPO.getCreateUserName());
		// 更新时间
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getUpdateTime()), SysMenu::getUpdateTime, sysMenuPO.getUpdateTime());
		// 更新人ID
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getUpdateUserId()), SysMenu::getUpdateUserId, sysMenuPO.getUpdateUserId());
		// 更新人姓名
		queryWrapper.like(ObjectUtil.isNotEmpty(sysMenuPO.getUpdateUserName()), SysMenu::getUpdateUserName, sysMenuPO.getUpdateUserName());
		// 租户ID
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysMenuPO.getTenantId()), SysMenu::getTenantId, sysMenuPO.getTenantId());
		// 创建时间时间区间查询
		queryWrapper.ge(ObjectUtil.isNotEmpty(StringRange.getOne(sysMenuPO.getCreateTimeBetween(),0)), SysMenu::getCreateTime,StringRange.getOne(sysMenuPO.getCreateTimeBetween(),0));
		queryWrapper.le(ObjectUtil.isNotEmpty(StringRange.getOne(sysMenuPO.getCreateTimeBetween(),1)), SysMenu::getCreateTime,StringRange.getOne(sysMenuPO.getCreateTimeBetween(),1));
		// 更新时间时间区间查询
		queryWrapper.ge(ObjectUtil.isNotEmpty(StringRange.getOne(sysMenuPO.getUpdateTimeBetween(),0)), SysMenu::getUpdateTime,StringRange.getOne(sysMenuPO.getUpdateTimeBetween(),0));
		queryWrapper.le(ObjectUtil.isNotEmpty(StringRange.getOne(sysMenuPO.getUpdateTimeBetween(),1)), SysMenu::getUpdateTime,StringRange.getOne(sysMenuPO.getUpdateTimeBetween(),1));

		queryWrapper.orderByDesc(SysMenu::getCreateTime,SysMenu::getMenuId);
		return queryWrapper;
	}

	 /**
	  * @describe 分页查询菜单权限表
	  * @author zhuhui
	  * @date 2024-11-26 22:58:21
	  */
	@Override
	public Page<SysMenu> getSysMenuPage(Page page, SysMenuPO sysMenuPO){
		LambdaQueryWrapper<SysMenu> queryWrapper = this.generateQueryWrapper(sysMenuPO);
        return this.baseMapper.selectPage(page, queryWrapper);
	}
	
	/**
     * @describe 查询菜单权限表list
     * @author  zhuhui
     * @date  2024-11-26 22:58:21
     */
	@Override
	public List<SysMenu> getSysMenuList(SysMenuPO sysMenuPO){
		LambdaQueryWrapper<SysMenu> queryWrapper = this.generateQueryWrapper(sysMenuPO);
        return this.baseMapper.selectList(queryWrapper);
	}
	
	/**
     * @describe 获取一条数据 菜单权限表
     * @author  zhuhui
     * @date  2024-11-26 22:58:21
     */
	@Override
	public SysMenu getSysMenu(SysMenuPO sysMenuPO){
		LambdaQueryWrapper<SysMenu> queryWrapper = this.generateQueryWrapper(sysMenuPO);
        queryWrapper.last("LIMIT 1");
        return this.baseMapper.selectOne(queryWrapper);
	}

    /**
     * @describe 新增菜单权限表
     * @author  zhuhui
     * @date  2024-11-26 22:58:21
     */
	@Override
	public Integer saveSysMenu(SysMenuPO sysMenuPO) {
		if (ObjectUtil.isEmpty(sysMenuPO.getName())){
			throw new RuntimeException("菜单名称不能为空");
		}
		if (ObjectUtil.isEmpty(sysMenuPO.getParentId())){
			throw new RuntimeException("父菜单ID不能为空");
		}
		if (ObjectUtil.isEmpty(sysMenuPO.getSort())){
			sysMenuPO.setSort(0);
		}

        sysMenuPO.setDelFlag(0);
		sysMenuPO.setTenantId(SecurityUtils.getUser().getTenantId());// 租户ID
		sysMenuPO.setCreateTime(LocalDateTime.now());
		sysMenuPO.setCreateUserId(SecurityUtils.getUser().getUserId());// 创建人
		sysMenuPO.setCreateUserName(SecurityUtils.getUser().getRealName());// 创建人
		sysMenuPO.setUpdateTime(LocalDateTime.now());
		SysMenu sysMenu = BeanUtil.copyProperties(sysMenuPO, SysMenu.class);
		this.save(sysMenu);
		return sysMenu.getMenuId();
	}

	/**
     * @describe 修改菜单权限表
     * @author  zhuhui
     * @date  2024-11-26 22:58:21
     */
	@Override
	public String updateSysMenu(SysMenuPO sysMenuPO) {
		if (ObjectUtil.isEmpty(sysMenuPO.getMenuId())) {
			throw new RuntimeException("id为空");
		}
		if (ObjectUtil.isEmpty(sysMenuPO.getName())){
			throw new RuntimeException("菜单名称不能为空");
		}

		sysMenuPO.setUpdateUserId(SecurityUtils.getUser().getUserId());// 更新人
		sysMenuPO.setUpdateUserName(SecurityUtils.getUser().getRealName());// 更新人
		sysMenuPO.setUpdateTime(LocalDateTime.now());
		SysMenu sysMenu = BeanUtil.copyProperties(sysMenuPO, SysMenu.class);
		this.updateById(sysMenu);
		return "修改成功";
	}

	/**
     * @describe 通过id删除菜单权限表
     * @author  zhuhui
     * @date  2024-11-26 22:58:21
     */
	@Override
	public String removeSysMenu(SysMenuPO sysMenuPO) {
		if (ObjectUtil.isEmpty(sysMenuPO.getBatchDel())) {
			throw new RuntimeException("删除数据未选择");
		}
		LambdaUpdateWrapper<SysMenu> removeWrapper = new LambdaUpdateWrapper<>();
		removeWrapper.in(SysMenu::getMenuId, sysMenuPO.getBatchDel());
		removeWrapper.set(SysMenu::getDelFlag,1);
		removeWrapper.set(SysMenu::getUpdateUserId,SecurityUtils.getUser().getUserId());// 更新人
		removeWrapper.set(SysMenu::getUpdateUserName,SecurityUtils.getUser().getRealName());// 更新人
		removeWrapper.set(SysMenu::getUpdateTime,LocalDateTime.now());

		this.update(removeWrapper);
		return "删除成功";
	}

	@Override
	public List<SysMenu> treeSysMenu(SysMenuPO sysMenuPO) {
		sysMenuPO.setRootId(ObjectUtil.isEmpty(sysMenuPO.getRootId())?0:sysMenuPO.getRootId());
		List<SysMenu> sysMenuList = this.getSysMenuList(sysMenuPO);
		sysMenuList = sysMenuList.stream().sorted(Comparator.comparing(SysMenu::getSort).reversed()).collect(Collectors.toList());
		List<SysMenu> collect = sysMenuList.stream()
				.filter(sysMenu -> ObjectUtil.equal(sysMenu.getParentId(),sysMenuPO.getRootId()))
				.collect(Collectors.toList());
		for (SysMenu sysMenu : collect) {
			sysMenu.setChildren(buildChildren(sysMenu.getMenuId(),sysMenuList));
		}
		return collect;
	}

	private static List<SysMenu> buildChildren(Integer id, List<SysMenu> sysMenuList) {
		List<SysMenu> children = new ArrayList<>();
		for (SysMenu sysMenu : sysMenuList) {
			if (ObjectUtil.isEmpty(sysMenu.getParentId()) || ObjectUtil.equal(sysMenu.getParentId(),0)){
				continue;
			}
			if (sysMenu.getParentId().equals(id)){
				children.add(sysMenu);
			}
		}
		for (SysMenu child : children) {
			child.setChildren(buildChildren(child.getMenuId(),sysMenuList));
		}
		return children;
	}

}

